/*
 * Copyright 2024 LinQingYing. and contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The use of this source code is governed by the Apache License 2.0,
 * which allows users to freely use, modify, and distribute the code,
 * provided they adhere to the terms of the license.
 *
 * The software is provided "as-is", and the authors are not responsible for
 * any damages or issues arising from its use.
 *
 */

package com.linqingying.cangjie.ide.completion.back.weighers

import com.linqingying.cangjie.ide.completion.back.positionContext.CangJieRawPositionContext
import com.linqingying.cangjie.ide.completion.back.positionContext.CangJieSuperReceiverNameReferencePositionContext
import com.linqingying.cangjie.psi.UserDataProperty
import com.intellij.codeInsight.completion.CompletionSorter
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementWeigher
import com.intellij.openapi.util.Key

//
//import com.linqingying.cangjie.analyzer.CangJieAnalysisSession
//import com.intellij.codeInsight.completion.CompletionSorter
//import com.intellij.codeInsight.lookup.LookupElement
//import com.intellij.codeInsight.lookup.WeighingContext
//
//
internal object Weighers {
//    context(CangJieAnalysisSession)
//    fun applyWeighsToLookupElement(
//        context: WeighingContext,
//        lookupElement: LookupElement,
//        symbolWithOrigin: CjSymbolWithOrigin?,
//    ) {
//        ExpectedTypeWeigher.addWeight(context, lookupElement, symbolWithOrigin?.symbol)
//        KindWeigher.addWeight(lookupElement, symbolWithOrigin?.symbol, context)
//
//        if (symbolWithOrigin == null) return
//        val symbol = symbolWithOrigin.symbol
//
//        val availableWithoutImport = symbolWithOrigin.origin is CompletionSymbolOrigin.Scope
//
//        DeprecatedWeigher.addWeight(lookupElement, symbol)
//        PreferGetSetMethodsToPropertyWeigher.addWeight(lookupElement, symbol)
//        NotImportedWeigher.addWeight(context, lookupElement, symbol, availableWithoutImport)
//        ClassifierWeigher.addWeight(lookupElement, symbol, symbolWithOrigin.origin)
//        VariableOrFunctionWeigher.addWeight(lookupElement, symbol)
//        K2SoftDeprecationWeigher.addWeight(lookupElement, symbol, context.languageVersionSettings)
//
//        if (symbol !is CjCallableSymbol) return
//
//        PreferContextualCallablesWeigher.addWeight(lookupElement, symbol, context.contextualSymbolsCache)
//        PreferFewerParametersWeigher. addWeight(lookupElement, symbol)
//    }
//
//    context(CangJieAnalysisSession)
//    fun applyWeighsToLookupElementForCallable(
//        context: WeighingContext,
//        lookupElement: LookupElement,
//        signature: CjCallableSignature<*>,
//        symbolOrigin: CompletionSymbolOrigin,
//    ) {
//        CallableWeigher.addWeight(context, lookupElement, signature, symbolOrigin)
//
//        applyWeighsToLookupElement(context, lookupElement, CjSymbolWithOrigin(signature.symbol, symbolOrigin))
//    }
//
    fun addWeighersToCompletionSorter(sorter: CompletionSorter, positionContext: CangJieRawPositionContext): CompletionSorter =
        sorter
            .weighBefore(
                PlatformWeighersIds.STATS,
                CompletionContributorGroupWeigher.Weigher,
//                ExpectedTypeWeigher.Weigher,
//                DeprecatedWeigher.Weigher,
//                PriorityWeigher.Weigher,
//                PreferGetSetMethodsToPropertyWeigher.Weigher,
//                NotImportedWeigher.Weigher,
//                KindWeigher.Weigher,
//                CallableWeigher.Weigher,
//                ClassifierWeigher.Weigher,
            )
            .weighAfter(
                PlatformWeighersIds.STATS,
//                VariableOrFunctionWeigher.Weigher
            )
            .weighBefore(
                PlatformWeighersIds.PREFIX,
//                K2SoftDeprecationWeigher.Weigher,
//                VariableOrParameterNameWithTypeWeigher.Weigher
            )
            .weighAfter(
                PlatformWeighersIds.PROXIMITY,
//                ByNameAlphabeticalWeigher.Weigher,
//                PreferFewerParametersWeigher.Weigher,
            )
//            .weighBefore(getBeforeIdForContextualCallablesWeigher(positionContext), PreferContextualCallablesWeigher.Weigher)
//
    private fun getBeforeIdForContextualCallablesWeigher(positionContext: CangJieRawPositionContext): String =
        when (positionContext) {
            // prefer contextual callable when completing reference after "super."
//            is CangJieSuperReceiverNameReferencePositionContext -> ExpectedTypeWeigher.WEIGHER_ID
            else -> PlatformWeighersIds.PROXIMITY
        }

    private object PlatformWeighersIds {
        const val PREFIX = "prefix"
        const val STATS = "stats"
        const val PROXIMITY = "proximity"
    }
}
internal object CompletionContributorGroupWeigher {
    object Weigher : LookupElementWeigher(WEIGHER_ID) {
        override fun weigh(element: LookupElement): Comparable<*>? =
            element.groupPriority
    }

    var LookupElement.groupPriority by UserDataProperty(Key<Int>("GROUP_PRIORITY"))


    const val WEIGHER_ID = "cangjie.group.id"
}


